#pragma once
#include <vector>
#include <unordered_map>
#include <algorithm>

#include "constants.h"
#include "classes.h"
#include "tools.h"
#include "optimizer_tools.h"
using namespace std;

class OptCenter
{
public:
    vector<vector<BwType>> edge_site_bw_type_vec;
    vector<BwType> center_site_bw_type_vec;
    int edge_site_low_bw[MAX_N];
    int edge_site_high_bw[MAX_N];
    long long center_site_low_bw;
    long long center_site_high_bw;
    AssignInfo *assign_info;
    int edge_low_index;
    int edge_hight_index;
    int center_low_index;
    int center_hight_index;
    double total_score;
    double edge_site_score;
    double center_site_score;
    int min_stream;

    OptCenter(AssignInfo &assign_info);
    double opt(double edge_low_quantile, double edge_hight_quantile, double center_low_quantile, double center_hight_quantile, int min_stream);

private:
    void stream_merge_optimize_assign_t(int t);
    void stream_merge_crucial_center(int t, TAssign *tassign);
    bool check_is_score_decrease(int from_site_id, int to_site_id, int stream_id, int client_id, int bandwidth, TAssign *tAssign,
                                 int &gap_score, int &decrease_score, int &left_allo_bw);
    void get_stream_bw_from_connect_client(int t, TAssign *tAssign, vector<int> &safe_bw_uppers, int target_site_id, int target_steam_id);

    void refresh_state();
    void refresh_edge_site_state(int site_id);
    void refresh_center_site_state();
    vector<int> get_safe_bw_uppers(int t, TAssign *tassign);
};
